import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;


@SuppressWarnings("serial")
public class StatisticsServlet extends HttpServlet{
	private final String shopKey = "8259472FBED5DE4AD1FB0839";
	private Namespace nameSpace = Namespace.getNamespace("http://www.cs.au.dk/dWebTek/2011");
	private int maxHeight = 0;

	//a list of items with statistics
	private ArrayList<itemStatistics> itemStat = new ArrayList<itemStatistics>();


	//	<w:sale>
	//	    <w:saleTime>1299441414333</w:saleTime>
	//	    <w:saleAmount>2</w:saleAmount>
	//	    <w:shopID>16</w:shopID>
	//	    <w:itemID>978</w:itemID>
	//	    <w:customerID>576</w:customerID>
	//	    <w:saleItemPrice>1336</w:saleItemPrice>
	//	 </w:sale>


	@SuppressWarnings("unchecked")
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		itemStat = new ArrayList<itemStatistics>();
		PrintWriter out = response.getWriter();
		
		out.println("<a href=\"index.jsp\">Return to front page</a>");

		try {
			//build a list of sales
			Document itemSales = new SAXBuilder().build("http://services.brics.dk/java/cloud//listShopSales?shopKey=" + shopKey);
			List<Element> sales = itemSales.getRootElement().getChildren("sale", nameSpace);

			//build up list of individual elements
			for(Element sale : sales){
				String itemID = sale.getChildText("itemID", nameSpace);
				int saleAmount = Integer.parseInt(sale.getChildText("saleAmount", nameSpace));
				int saleItemPrice = Integer.parseInt(sale.getChildText("saleItemPrice", nameSpace));
				
//				System.out.println(itemID);

				itemStatistics item = getItemStatisticsInList(itemID);
				item.addSale(saleAmount, saleItemPrice);
			}

			getItemNames();

			printStatsTable(out);
			
			printGraphs(out);

		} catch (JDOMException e) {
			e.printStackTrace();
		}
	}

	/**
	 * print the graphs on the page
	 * @param out the printwriter to use
	 */
	private void printGraphs(PrintWriter out) {
		
		String chart = "https://chart.googleapis.com/chart";
		String chxt = "chxt=y";
		String chbh = "chbh=a,5,100";
		String chs = "chs=800x300";
		String cht = "cht=bvs";
		String chco = "chco=3D7930";
		String chd = "chd=t:"; //data
		String chm = "chm=";//+ "tTest1,000000,0,0,11|" + "tTest2,000000,0,1,11"; //
		String chxr = "chxr=0,0," + maxHeight;
		
		Iterator<itemStatistics> ite = itemStat.iterator();
		int i = 0;
		while(ite.hasNext()){
			itemStatistics item = ite.next();
			chd += (double)item.totalValueSold / (double)maxHeight * 100 + ",";
			chm += "t" +item.itemName + ",000000,0,"+ i +",11|";
			i++;
		}
		chd = chd.substring(0, chd.lastIndexOf(','));
		chm = chm.substring(0, chm.lastIndexOf('|'));
		
		String img = chart + "?" + chxt + "&" + chbh + "&" + chs + "&" + cht + "&" + chco + "&" + chd + "&" + chm + "&" + chxr;
		out.println("<img src=\"" + img + "\" />");
	}

	/**
	 * print table containing stats of each sale
	 * @param out the printwriter to write to
	 */
	private void printStatsTable(PrintWriter out) {
		//define top lvl table element (root)
		Element table = new Element("table");
		table.setAttribute("border", "1");

		//create doc with table as root element
		Document itemsXml = new Document(table);


		//define titels for tabel
		{
			Element tr = new Element("tr");
			table.addContent(tr);

			Element td = new Element("th"); //itemnr
			td.setText("ItemID");
			tr.addContent(td);

			td = new Element("th"); //name
			td.setText("Movie Name");
			tr.addContent(td);

			td = new Element("th"); //sold
			td.setText("Amount sold");
			tr.addContent(td);
			
			td = new Element("th"); //total sold
			td.setText("Total value sold");
			tr.addContent(td);
		}

		for(itemStatistics item : itemStat){
			//row
			Element tr = new Element("tr");
			table.addContent(tr);

			//item name
			Element td = new Element("td");
			td.setText(	item.itemID );
			tr.addContent(td);

			//item number
			td = new Element("td");
			td.setText(	item.itemName );
			tr.addContent(td);

			//item amount sold
			td = new Element("td");
			td.setText(	item.amountSold	+ "");
			tr.addContent(td);
			
			//item total value sold
			td = new Element("td");
			td.setText(	item.totalValueSold + "");
			tr.addContent(td);
			
			//check if this is the best selling product
			maxHeight = Math.max(maxHeight, item.totalValueSold);
		}

		XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
		try {
			outputter.output(itemsXml, out);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * method to match the names to the itemlist
	 */
	@SuppressWarnings("unchecked")
	private void getItemNames() {
		try {
			Document itemSales = new SAXBuilder().build("http://services.brics.dk/java/cloud//listItems?shopID=16");
			List<Element> items = itemSales.getRootElement().getChildren("item", nameSpace);

			//build up list of individual elements
			for(Element item : items){
				String itemID = item.getChildText("itemID", nameSpace);
				String itemName = item.getChildText("itemName", nameSpace);
				
				Iterator<itemStatistics> itemStatIte = itemStat.iterator();
				while( itemStatIte.hasNext() ){
					itemStatistics tempItem = itemStatIte.next();
					if(tempItem.itemID.equals(itemID)){
						tempItem.itemName = itemName;
					}
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/**
	 * get the item from the local list, or add it to it
	 */
	private itemStatistics getItemStatisticsInList(String itemID){
		//check for duplicate
		Iterator<itemStatistics> itemStatIte = itemStat.iterator();
		while(itemStatIte.hasNext()){
			itemStatistics tempItem = itemStatIte.next();
			if(tempItem.itemID.equals(itemID))
			{
				return tempItem;
			}
		}

		//if no matching item found, add it to list
		itemStatistics newItem = new itemStatistics(itemID);
		itemStat.add(newItem);
		return newItem;
	}

	private class itemStatistics{
		public itemStatistics(String itemID) {
			this.itemID = itemID;
		}

		public void addSale(int saleAmount, int salePrice){
			amountSold += saleAmount;
			totalValueSold += saleAmount * salePrice;
		}

		public String toString(){
			return itemID + " " + amountSold + " " + itemName;
		}

		public String itemName = "";
		public String itemID = "";
		public int amountSold = 0;
		public int totalValueSold = 0;
	}
}
